import 'package:flutter/material.dart';

class ListViewPage extends StatelessWidget{
  static const String routeName = "/ListViewPage";
  @override
  Widget build(BuildContext context) {
    return
      // listViewConstructor();
      // listviewBuilder();

      listViewCustom();



  }

  ListView listViewCustom() {
    return ListView.custom(
      scrollDirection: Axis.vertical,
      childrenDelegate:
      MyChildrenDelegate((BuildContext context, int index) {
        return Container(
          height: 50.0,
          alignment: Alignment.center,
          color: Colors.lightBlue[100 * (index % 9)],
          child: Text('list item $index'),
        );
      },
          childCount: 50),
    );
  }



  ListView listViewConstructor() {
    return ListView(
      //item 高度会适配 item填充的内容的高度
      shrinkWrap: true,
      padding: EdgeInsets.all(50.0),
      children: <Widget>[
         Text("test",),
         Icon(Icons.android, color: Colors.yellow,),
         Icon(Icons.cabin, color: Colors.red,),
      ],
    );
  }

  Widget listviewBuilder(){
    return ListView.builder(
      // item 的个数
      itemCount: 20,
      //设置滑动方向 Axis.horizontal 水平  默认 Axis.vertical 垂直
      scrollDirection: Axis.vertical,
      //内间距
      padding: EdgeInsets.all(10.0),
      //是否倒序显示 默认正序 false  倒序true
      reverse: false,
      //false，如果内容不足，则用户无法滚动 而如果[primary]为true，它们总是可以尝试滚动。
      primary: true,
      //确定每一个item的高度 会让item加载更加高效
      itemExtent: 50.0,
      //item 高度会适配 item填充的内容的高度 多用于嵌套listView中 内容大小不确定 比如 垂直布局中 先后放入文字 listView （需要Expend包裹否则无法显示无穷大高度 但是需要确定listview高度 shrinkWrap使用内容适配不会） 文字
      shrinkWrap: true,
      //滑动类型设置
      //new AlwaysScrollableScrollPhysics() 总是可以滑动
      // NeverScrollableScrollPhysics禁止滚动
      // BouncingScrollPhysics 内容超过一屏 上拉有回弹效果
      // ClampingScrollPhysics 包裹内容 不会有回弹
      physics: new ClampingScrollPhysics(),

      // cacheExtent  设置预加载的区域
      // cacheExtent 强制设置为了 0.0，从而关闭了“预加载”
      cacheExtent: 30.0,

      //滑动监听
      //        controller ,
      itemBuilder: (BuildContext context, int index) {
        //根据index返回不同的widget
        return Text("title $index");
      },
    );

  }

}

/**
 * 继承SliverChildBuilderDelegate  可以对列表的监听
 */
class MyChildrenDelegate extends SliverChildBuilderDelegate {
  MyChildrenDelegate(
      Widget Function(BuildContext, int) builder, {
        int childCount=0,
        bool addAutomaticKeepAlive = true,
        bool addRepaintBoundaries = true,
      }) : super(builder,
      childCount: childCount,
      addAutomaticKeepAlives: addAutomaticKeepAlive,
      addRepaintBoundaries: addRepaintBoundaries);

  ///监听 在可见的列表中 显示的第一个位置和最后一个位置
  @override
  void didFinishLayout(int firstIndex, int lastIndex) {
    print('firstIndex: $firstIndex, lastIndex: $lastIndex');
  }

  ///可不重写 重写不能为null  默认是true  添加进来的实例与之前的实例是否相同 相同返回true 反之false
  ///listView 暂时没有看到应用场景 源码中使用在 SliverFillViewport 中
  @override
  bool shouldRebuild(SliverChildBuilderDelegate oldDelegate) {
    // TODO: implement shouldRebuild
    print("oldDelegate$oldDelegate");
    return super.shouldRebuild(oldDelegate);
  }
}
